#!/bin/sh /etc/rc.common

START=55
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
EXTRA_COMMANDS="firewall restart"

APP='dnscrypt-proxy'
service_bin='/usr/sbin/dnscrypt-proxy'
dnsmasq_conf='/etc/dnsmasq.conf'
dnsmasq_dns_port='53'

prerouting_check() {
	if iptables -t nat --list zone_lan_prerouting &>/dev/null; then
		PREROUTING='zone_lan_prerouting'
	else
		PREROUTING='PREROUTING'
	fi
}

mode_dnsmasq_enable() {
	grep -q "server=127.0.0.1#$local_port" "$dnsmasq_conf" || {
		echo -e "#${APP}_start\nno-resolv\nserver=127.0.0.1#$local_port\n#${APP}_end">>"$dnsmasq_conf"
		pidof dnsmasq &>/dev/null && /etc/init.d/dnsmasq restart
	}
}

mode_dnsmasq_disable() {
	FILE_DATA=$(cat "$dnsmasq_conf")
	FIND_START=$(echo -e "$FILE_DATA"|grep -n -x -m 1 "#${APP}_start")
	[ -z "$FIND_START" ] || {
		FIND_END=$(echo -e "$FILE_DATA"|grep -n -x -m 1 "#${APP}_end")
	}
	[ -z "$FIND_END" ] || {
		sed -i "${FIND_START%%:*},${FIND_END%%:*}d" "$dnsmasq_conf"
		pidof dnsmasq &>/dev/null && /etc/init.d/dnsmasq restart
	}
}

mode_tcp_forward_enable() {
	[ -z "$PREROUTING" ] && prerouting_check
	iptables -t nat -A $PREROUTING -p tcp --dport $dnsmasq_dns_port -m comment --comment "DNSCRYPT" -j REDIRECT --to-ports $local_port
}

mode_tcp_forward_disable() {
	[ -z "$PREROUTING" ] && prerouting_check
	iptables-restore <<-EOF || {
		$(echo -e "$(iptables-save -t nat)" | sed "/DNSCRYPT/d")
	EOF
		clean_rules=$(iptables -t nat --list-rules $PREROUTING | grep "DNSCRYPT")
		[ -z "$clean_rules" ] || {
			clean_rules=$(echo -e "$clean_rules" | sed 's/\-A/\-D/' | awk '{print "iptables -t nat " $0}')
			eval "$clean_rules"
		}
	}
}

mode() {
	case $mode in
		0)
			echo "Mode: Normal"
			mode_tcp_forward_disable
			mode_dnsmasq_disable
			;;
		1)
			echo "Mode: Dnsmasq"
			mode_tcp_forward_disable
			mode_dnsmasq_enable
			;;
		2)
			echo "Mode: UDP Forward"
			mode_dnsmasq_disable
			mode_tcp_forward_disable
			mode_tcp_forward_enable
			;;
	esac
}

enabled_check() {
	config_load "$APP"
	config_get enabled config enabled
	[ "$enabled" = '1' ] || {
		return 1
	}
	return 0
}

service_options() {
	config_get mode config mode '0'
	config_get local_address config local_address '127.0.0.1'
	config_get local_port config local_port '2053'
	config_get resolvers_list config resolvers_list '/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv'
	config_get resolver config resolver 'opendns'
	service_option="-a ${local_address}:${local_port} -L $resolvers_list -R $resolver"
}

service_check() {
	FIND_DATA=$(ps|grep "$1"|grep -v "grep $1")
	[ -z "$FIND_DATA" ] && return 1
	return 0
}

service_process() {
	service_check "$1" && echo "Start $1 ... Already running. Please try \"stop\" or \"restart\"" && return 1
	service_start $1 $2
	service_check "$1" && echo "Start $1 ... OK" && return 0
	echo "Start $1 ... Fail" && return 1
}

service_run() {
	service_options
	service_process "$service_bin" "$service_option" && mode && return 0
	return 1
}

start() {
	enabled_check || exit 0
	service_run && echo "Done."
}

stop() {
	service_stop $service_bin
	mode_dnsmasq_disable
}

restart() {
	enabled_check || {
		stop
		exit 0
	}
	service_stop $service_bin
	service_run && echo "Done."
}

firewall() {
	config_load "$APP"
	config_get mode config mode
	[ "$mode" = '2' ] && {
		config_get local_port config local_port '2053'
		mode_tcp_forward_enable
	}
	exit 0
}
